//     <one line to give the program's name and a brief idea of what it does.>
//     Copyright (C) 2021  Qiufeng54321
//
//     This program is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
//
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
//
//     You should have received a copy of the GNU General Public License
//     along with this program.  If not, see <https://www.gnu.org/licenses/>.

//
// Created by mac on 2021/6/2.
//

#include "MapGroup.h"
#include <utility>
#include <vector>
#include <sstream>

namespace williamcraft {
    MapGroup::MapGroup(std::string path) : path(path) {
        map_file = std::fstream(path, std::ios::in | std::ios::out | std::ios::binary);
    }

    std::unique_ptr<map::MetadataT> MapGroup::create_metadata() {
        std::unique_ptr<map::MetadataT> metadata = std::make_unique<map::MetadataT>();
        metadata->audio_offset = 0;
        metadata->audio_path = "";
        metadata->author = "unknown";
        metadata->composer = "unknown";
        metadata->tempo = 0;
        metadata->tags = {};
        return metadata;
    }

    std::unique_ptr<map::DifficultyT> MapGroup::create_difficulty(std::string name) {
        std::unique_ptr<map::MapT> map = std::make_unique<map::MapT>();
        map->notes = {};
        std::unique_ptr<map::DifficultyT> difficulty = std::make_unique<map::DifficultyT>();
        difficulty->name = std::move(name);
        difficulty->map = std::move(map);
        return difficulty;
    }

    MapGroup MapGroup::create_map(std::string path) {
        map::MapGroupT mapGroup;
        MapGroup map_group(std::move(path));
        map_group.map_group = std::make_unique<map::MapGroupT>();
        map_group.map_group->metadata = map_group.create_metadata();
        map_group.map_group->difficulties.push_back(map_group.create_difficulty("normal"));
        map_group.save();
//        map_group.load();
        return map_group;
    }

    std::unique_ptr<map::MapGroupT> MapGroup::get_map() {
        return std::move(map_group);
    }

    void MapGroup::save() {
        map_file.open(path, std::ios::out | std::ios::binary);
        builder.Finish(map::MapGroup::Pack(builder, map_group.get()));
        map_file.write(reinterpret_cast<const char *>(builder.GetBufferPointer()), builder.GetSize());
        map_file.close();
    }

    void MapGroup::load() {
        map_file.open(path, std::ios::in | std::ios::binary);
        std::stringstream buffer;
        buffer << map_file.rdbuf();
        map_file.close();
        map::GetMutableMapGroup((void *) buffer.str().c_str())->UnPackTo(map_group.get());
    }
}